/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.just.dusin.ooii.component.kj;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;
import org.apache.log4j.Logger;
import org.dusin.webcoal.exception.OOIIException;
import org.just.dusin.ooii.component.Source;
import org.just.dusin.ooii.util.DeviceData;

/**
 *
 * @author Administrator
 */
public class KJ215Source extends Source {

    private static Logger logger = Logger.getLogger(KJ215Source.class.getName());
    CommPortIdentifier commPortId;   
    SerialPort serialPort;
    OutputStream outputStream;
    InputStream inputStream;
    private String portId = "COM1"; 
    private int inteval = 300; //循环延时
    private int delay = 500;  //设备延时，读取数据    
    private int no=1;   //设备编号
    private Queue<Integer> shiftQueue = new LinkedList<Integer>();    //最近10次采集数据的成功 与失败，为了得到采集数据是否正常
    private double preTotal = -1;
    
    //获取当前采集数据的成功率
    public int getSuccRate(){
        int r=0;
        for(Integer i:shiftQueue){
            if(i==1)
                r++;
        }
        return r;
    }
    
    //将当前是否成功的状态置入对列
    private void addQueue(int s){
        if(shiftQueue.size()>=10){
            shiftQueue.poll();
        }
        shiftQueue.add(s);
    }
    
    public int getDelay() {
        return delay;
    }

    public void setDelay(int delay) {
        this.delay = delay;
    }

    public int getInteval() {
        return inteval;
    }

    public void setInteval(int inteval) {
        this.inteval = inteval;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getPortId() {
        return portId;
    }

    public void setPortId(String portId) {
        this.portId = portId;
    }

    
    
    @Override
    public void initComponent(Properties props) {        
    }

    @Override
    public void destroyComponent() throws Exception {        
    }

    @Override
    public void run() {        
        
        while (!stop) {
            try {
                commPortId = CommPortIdentifier.getPortIdentifier(portId);
                serialPort = (SerialPort) commPortId.open("SimpleWriteApp", 2000);

                outputStream = serialPort.getOutputStream();
                inputStream = serialPort.getInputStream();

                serialPort.setSerialPortParams(9600,
                        SerialPort.DATABITS_8,
                        SerialPort.STOPBITS_1,
                        SerialPort.PARITY_MARK);

                byte[] address = new byte[]{(byte) 0x81};
                outputStream.write(address);
                Thread.sleep(100);

                byte[] readBuffer;
                serialPort.setSerialPortParams(9600,
                        SerialPort.DATABITS_8,
                        SerialPort.STOPBITS_1,
                        SerialPort.PARITY_SPACE);

                byte[] readCommand = new byte[]{(byte) 0x02, (byte) 0xfe, (byte) 00, (byte) 00, (byte) 00, (byte) 00, (byte) 0x81};
                outputStream.write(readCommand);

                Thread.sleep(delay);
                readBuffer = new byte[92];
                String msg;
                if (inputStream.available() > 0) {                    
                    int numBytes = inputStream.read(readBuffer);
                    //System.out.println();
                    if(numBytes==92&&DeviceData.isCheckValid(readBuffer)){
                        double currentTotal = DeviceData.getTotal(readBuffer);
                        double flowSpeed = DeviceData.getFlowSpeed(readBuffer);
                        double beltSpeed=DeviceData.getBeltSpeed(readBuffer);
                        byte shellOpen = readBuffer[90];
                        if(Math.abs(preTotal+1)<1e-6||Math.abs(currentTotal-preTotal)<60) { //对获取的数据进行监测
                            msg= DataPackage.packYBSJ(no,currentTotal,flowSpeed,beltSpeed,shellOpen,0);
                            preTotal= currentTotal;
                            addQueue(0);
                        }
                        else{
                            msg = DataPackage.packYBSJ(no,0,0,0,(byte)0,2);  //2表示有回应数据，但数据异常
                            addQueue(1);
                        }
                    }else{
                        msg = DataPackage.packYBSJ(no,0,0,0,(byte)0,2);  //2表示有回应数据，但数据异常
                        addQueue(1);
                        logger.error("仪表数据异常");
                    }                        
                }else{                    
                    msg = DataPackage.packYBSJ(no,0,0,0,(byte)0,1); //1表示指令发送，设备无响应
                    addQueue(1);
                    logger.error("仪表无数据返回");
                }                
                logger.info("处理消息"+msg);
                sink.process(msg);      //处理正常数据
            } catch (OOIIException ex) {
                ex.printStackTrace();
                logger.error("目的组件异常"+ex.getMessage());
            } catch (PortInUseException ex) {
                logger.error("该端口被占用");
            } catch (NoSuchPortException ex) {
                logger.error("该端口不存在");
            } catch (IOException e) {
                logger.error("IO异常:" + e.getMessage());
            } catch (InterruptedException e) {
                logger.warn("sleep被中断");
            } catch (UnsupportedCommOperationException e) {
                logger.error("不支持操作:" + e.getMessage());
            } finally {
                try {
                    if(inputStream!=null)
                        inputStream.close();
                    if(outputStream!=null)
                        outputStream.close();
                    if(serialPort!=null)
                        serialPort.close();
                    Thread.sleep(inteval);
                } catch (InterruptedException ex) {
                    logger.warn("sleep被中断");
                } catch (IOException ex) {
                    logger.error("IO异常：" + ex.getMessage());
                }
            }
        }
    }
}
